package com.teatrace.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.DetachedCriteria;

/**
 * 基本增删改查接口
 * @author ZZM
 *
 */
public interface BaseDao {
	
	public Long count(Class clazz) throws Exception;

	public <T> void save(T obj) throws Exception;
	
	public <T> void persist(T obj) throws Exception;
	
	public <T> void delete(T obj) throws Exception;
	
	public <T> void update(T obj) throws Exception;
	
	public <T> void saveOrUpdate(T obj) throws Exception;
	
	public <T> T load(Class<T> clazz, Serializable pk) throws Exception;
	
	public <T> T get(Class<T> clazz, Serializable pk) throws Exception;
	
	public <T> void batchSave(Collection<T> batchObj) throws Exception;
	
	public <T> void batchPersist(Collection<T> batchObj) throws Exception;
	
	public <T> void batchDelete(Collection<T> batchObj) throws Exception;
	
	public <T> void batchUpdate(Collection<T> batchObj) throws Exception;
	
	/**
	 * 通过obj的属性名为propertyName的值去查找<br>
	 * 例:<br>
	 * class User {									<Br>
	 * 		private long id;						<br>
	 * 		private String account;					<br>
	 * }											<br>
	 * <br>
	 * main() {										<Br>
	 * 		User user = new User();											<br>
	 * 		user.setAccount("1234");										<br>
	 * 		dao.listByPorperty(User.class, user, "account");				<br>
	 * }
	 * 
	 * 上述代码的将发出SQL：hql -> from User user where user.account="1234"		<br>
	 * 					   sql -> select * from User where account="1234"		<br>
	 * @param <T>
	 * @param clazz
	 * @param obj
	 * @param propertyName
	 * @return
	 * @throws Exception
	 */
	public <T> List<T> listByProperty(Class<T> clazz, T obj, String propertyName) throws Exception;
	
	/**
	 * 查询全部数据
	 * @param clazz 指定查询的目标, 为null时抛出	java.lang.NullPointerException
	 * @return List<T>
	 */
	public <T> List<T> list(Class<T> clazz) throws Exception;
	
	/**
	 * 条件查询<br>
	 * BaseDao dao = DaoFactory.createBaseDao();<br>
	 * dao.getTransaction().begin();<Br>
	 * DetachedCriteria dc = dao.createDetachedCriteria(Field.class);<br>
	 * dc.add(Restrictions.eq("number", "JDFH9768DFD987987"));<br>
	 * List list = dao.listByCriteria(dc);<br>
	 * dao.getTransaction().commit();<br>
	 * dao.close();	<br>
	 * @param dc 指定的查询条件, 为null时不会抛出异常, 而是无条件进行
	 * @return List<T>
	 */
	public <T> List<T> listByCriteria(DetachedCriteria dc) throws Exception;
	
	/**
	 * 分页条件查询<br>
	 * 当然, 可以直接使用 listByCriteria
	 * @param dc 指定的查询条件, 为null时不会抛出异常, 而是无条件进行
	 * @param firstResult 开始点, 为负时刚认为是 0
	 * @param maxResult 查询条数, 当大于可查询条数时按指定的数据库的分页方式进行查询, <br>
	 * 					为负时抛出 java.lang.IllegalArgumentException
	 * @return List<T>
	 */
	public <T> List<T> listByCriteria(DetachedCriteria dc, int firstResult, int maxResult) throws Exception;
	
	
	
	/**
	 * 根据条件去计数
	 * @param dc 指定的查询条件, 为null时不会抛出异常, 而是无条件进行
	 * @return java.lang.Long 
	 */
	public <T> Long countByCriteria(DetachedCriteria dc) throws Exception;
	
	/**
	 * 通过HQL去查询
	 * @param hql 一个HQL
	 * @return List<T>
	 */
	public <T> List<T> listByHQL(String hql) throws Exception;
	
	/**
	 * 根据hibernate 配置的Query去查询
	 * @param name Query Name
	 * @param params Query参数
	 * @return List<T>
	 */
	public <T> List<T> listByNamedQuery(String name, Map<String, Object> params) throws Exception;
	
	/**
	 * Query分页
	 */
	public <T> List<T> listByPage(Class<T> clazz, int firstResult, int maxResults) throws Exception;
	
	/**
	 * 创建指定 VO 的 DetachedCriteria
	 * @param clazz 指定哪个VO
	 * @return DetachedCriteria
	 */
	public DetachedCriteria createDetachedCriteria(Class clazz);
	
	
	public Transaction getTransaction();
	
	public Session getSession();
	
	public void close();
}
